/*
 * commons is a based project implemented
 * Copyright (C) 2024 Jasmine
 */
package com.commons.core.validator;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.*;
import java.text.SimpleDateFormat;

import org.springframework.util.StringUtils;

import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;

/**
 * 使用：
 *
 * @author Jasmine
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@Constraint(validatedBy = DateValidator.DateValidatorHandle.class)
public @interface DateValidator {

    String message() default "日期格式不正确，正确格式应为yyyy-MM-dd";

    Class[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    String format() default "yyyy-MM-dd";

    boolean required() default true;

    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        DateValidator[] value();
    }

    class DateValidatorHandle implements ConstraintValidator<DateValidator, String> {

        private Boolean required;
        private String format;

        @Override
        public void initialize(DateValidator constraintAnnotation) {
            this.required = constraintAnnotation.required();
            this.format = constraintAnnotation.format();
        }

        @Override
        public boolean isValid(String dateValue, ConstraintValidatorContext constraintValidatorContext) {
            if (!StringUtils.hasLength(dateValue)) {
                // 校验是不是必填
                if (required) {
                    return false;
                } else {
                    return true;
                }
            } else {
                try {
                    // 校验日期格式
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
                    simpleDateFormat.parse(dateValue);
                    return true;
                } catch (Exception e) {
                    return false;
                }
            }
        }
    }

}
